package cmp.compile.panels;

/****************************************************
 * Defines the Add/Edit Panel for Methods
 * Note: CAS the Recip (recipacol best blast) is temporarily disabled as it is not 
 */
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import util.ui.UserPrompt;

import cmp.main.Globals;

public class EditMethodPanel extends JPanel {
	private static final long serialVersionUID = -3057836165213279944L;
	private final short OM = 0;
	private final short TR = 1;

	public EditMethodPanel(CompilePanel parentPanel) {
		theParentPanel = parentPanel;
		
		// the Prefix, Name, Remark and parameters are created in the following 3 classes
		pnlOrtho = new MethodOrthoMCLPanel(theParentPanel);
		pnlTrans = new MethodTransitivePanel(theParentPanel);
		//pnlRecip = new MethodBestRecipPanel(theParentPanel);
		pnlCust  = new MethodUserDefPanel(theParentPanel);
		
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
		setAlignmentX(Component.LEFT_ALIGNMENT);
		setBackground(Globals.BGCOLOR);
		
		lblMode = new JLabel("Method");
		cmbMode = new JComboBox();
		
		cmbMode.addItem(MethodOrthoMCLPanel.getMethodType());
		cmbMode.addItem(MethodTransitivePanel.getMethodType());
		cmbMode.addItem(MethodUserDefPanel.getMethodType());
		cmbMode.setSelectedIndex(0);
		cmbMode.setBackground(Globals.BGCOLOR);
		cmbMode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				updateMode();
			}
		});
		
		
		/** 
		 * the actionPerformed is in CompilePanel since it has to fill in the table
		 * with the results. 
		 * XXX Could it possibly be the other way around where it calls CompilePanel with
		 * the new row values? Then makes itself invisible and the main panel visible?
		 */
		btnKeep = new JButton("Keep");
		btnKeep.setBackground(Globals.BGCOLOR);
		btnKeep.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				boolean isValid = true;
				String prefix = getPrefix();
				String method = getMethodName();
				if(prefix.length() > 3) {
					JOptionPane.showMessageDialog(theParentPanel, "Prefix too long", "Must be less than 4 characters", JOptionPane.PLAIN_MESSAGE);
					System.err.println("Error: prefix value above 3 characters");
					isValid = false;
				}
				if (!prefix.matches("[\\w\\d]+"))
				{
					JOptionPane.showMessageDialog(theParentPanel, "Prefix contains invalid characters.\nUse letters,numbers,underscores.",
							"Invalid prefix", JOptionPane.PLAIN_MESSAGE);
					System.err.println("Error: prefix contains invalid characters");
					isValid = false;
				}
				String name = getMethodName();
				if (name.equals("")) {
					JOptionPane.showMessageDialog(theParentPanel, "Please enter a name.",
							"Missing name", JOptionPane.PLAIN_MESSAGE);
					System.err.println("Error: missiong name");
					isValid = false;
				}
				else if (!name.matches("[\\w\\d]+"))
				{
					JOptionPane.showMessageDialog(theParentPanel, "Name contains invalid characters.\nUse letters,numbers,underscores.",
							"Invalid name", JOptionPane.PLAIN_MESSAGE);
					System.err.println("Error: name contains invalid characters");
					isValid = false;
				}
				String cmt = getComment();
				if (cmt.contains("'") || cmt.contains("\""))
				{
					JOptionPane.showMessageDialog(theParentPanel, "Comment cannot contain quotes.",
							"Invalid comment", JOptionPane.PLAIN_MESSAGE);
					System.err.println("Error: comment contains quotes");
					isValid = false;					
				}
				if(isEditMode()) {
					int row = theParentPanel.getMethodPanel().getSelectedRow();
					
					for(int x=0; x<theParentPanel.getMethodPanel().getNumRows() && isValid; x++) {
						if(x != row && theParentPanel.getMethodPanel().getMethodPrefixAt(x).equals(prefix)) {
							JOptionPane.showMessageDialog(theParentPanel, "Duplicate prefix", "Must be unique", JOptionPane.PLAIN_MESSAGE);
							System.err.println("Duplicate prefix, cannot save");
							isValid = false;
						}
						// CAS 5July15 -- doesn't have to be unique, but is ambiguous in viewMulti if not
						if (x != row && theParentPanel.getMethodPanel().getMethodNameAt(row).equals(method)) {
							JOptionPane.showMessageDialog(theParentPanel, "Duplicate method name", "Must be unique", JOptionPane.PLAIN_MESSAGE);
							System.err.println("Duplicate method name, cannot save");
							isValid = false;
						}
					}
					
					if(isValid) {
						theParentPanel.getMethodPanel().setRow(row, getMethodName(), getMethodType(), getPrefix(), getComment(), getSettings());
						if(bLoaded) {
							theParentPanel.updateMethodRemark(getPrefix(), getComment());
						}
					}
				}
				else {
					for(int x=0; x<theParentPanel.getMethodPanel().getNumRows() && isValid; x++) {
						if(theParentPanel.getMethodPanel().getMethodPrefixAt(x).equals(prefix)) {
							JOptionPane.showMessageDialog(theParentPanel, "Duplicate prefix", "Must be unique", JOptionPane.PLAIN_MESSAGE);
							System.err.println("Duplicate prefix, cannot save");
							isValid = false;
						}
						if (theParentPanel.getMethodPanel().getMethodNameAt(x).equals(method)) {
							JOptionPane.showMessageDialog(theParentPanel, "Duplicate method name", "Must be unique", JOptionPane.PLAIN_MESSAGE);
							System.err.println("Duplicate method name, cannot save");
							isValid = false;
						}
					}
					if(isValid) {
						theParentPanel.getMethodPanel().addRow(getMethodName(), getMethodType(), getPrefix(), getComment(), getSettings());
					}
				}
				theParentPanel.getMethodPanel().updateTable();
				if(isValid) {
					theParentPanel.saveCPAVE();
					setVisible(false);
					theParentPanel.setMainPanelVisible(true);
				}
			}
		});
		
		btnDiscard = new JButton("Discard");
		btnDiscard.setBackground(Globals.BGCOLOR);
		btnDiscard.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				setVisible(false);
				theParentPanel.setMainPanelVisible(true);
			}
		});
		
		btnHelp = new JButton("Help");
		btnHelp.setBackground(Globals.HELPCOLOR);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				UserPrompt.displayHTMLResourceHelp(theParentPanel.getParentFrame(), "Edit method", "html/runMultiTCW/EditMethodPanel.html");
			}
		});

		JPanel temp = CompilePanel.getPanel(true);
		temp.add(lblMode);
		temp.add(Box.createHorizontalStrut(5));
		temp.add(cmbMode);
		temp.setMaximumSize(temp.getPreferredSize());
		temp.setMinimumSize(temp.getPreferredSize());
		
		add(temp);
		add(Box.createVerticalStrut(15));
		
		add(pnlOrtho);
		add(pnlTrans);
		add(pnlCust);
		
		JPanel buttonPanel = CompilePanel.getPanel(true);
		buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		buttonPanel.add(btnKeep);
		buttonPanel.add(Box.createHorizontalStrut(10));
		buttonPanel.add(btnDiscard);
		buttonPanel.add(Box.createHorizontalStrut(10));
		buttonPanel.add(btnHelp);
		buttonPanel.setMaximumSize(buttonPanel.getPreferredSize());
		buttonPanel.setMinimumSize(buttonPanel.getPreferredSize());
		
		add(Box.createVerticalStrut(15));
		temp = CompilePanel.getPanel(true);
		temp.add(Box.createHorizontalGlue());
		temp.add(buttonPanel);
		temp.add(Box.createHorizontalGlue());

		add(temp);
		
		setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		updateMode();
	}
	
	public boolean isEditMode() { return bEditMode; }
	public void setEditMode(boolean mode) { bEditMode = mode; }
	
	public boolean isLoaded() { return bLoaded; }
	public void setLoaded(boolean loaded) { 
		bLoaded = loaded;
		cmbMode.setEnabled(!loaded);
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setLoaded(bLoaded);
		else if(sel == TR) pnlTrans.setLoaded(bLoaded);
		//else if(sel == RH) pnlRecip.setLoaded(bLoaded);
		else pnlCust.setLoaded(bLoaded);
	}

	private void updateMode() {
		pnlOrtho.setVisible(false);
		pnlTrans.setVisible(false);
		//pnlRecip.setVisible(false);
		pnlCust.setVisible(false);
		
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setVisible(true);
		else if(sel == TR) pnlTrans.setVisible(true);
		//else if(sel == RH) pnlRecip.setVisible(true);
		else pnlCust.setVisible(true);
	}
	
	
	public String getMethodType() { return (String) cmbMode.getSelectedItem(); }
	public void setMethodType(String method) { cmbMode.setSelectedItem(method); }
	public void setMethodType(int method) { cmbMode.setSelectedIndex(method); }
	
	public String getMethodName() { 
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) return pnlOrtho.getMethodName();
		if(sel == TR) return pnlTrans.getMethodName();
		//if(sel == RB) return pnlRecip.getMethodName();
		return pnlCust.getMethodName();
	}
	
	public void setMethodName(String name) { 
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setMethodName(name);
		else if(sel == TR) pnlTrans.setMethodName(name);
		else pnlCust.setMethodName(name);
	}
	
	public String getPrefix() { 
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) return pnlOrtho.getPrefix();
		if(sel == TR) return pnlTrans.getPrefix();
		return pnlCust.getPrefix();
	}
	
	public void setPrefix(String prefix) { 
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setPrefix(prefix);
		else if(sel == TR) pnlTrans.setPrefix(prefix);
		else pnlCust.setPrefix(prefix);
	}
	
	public String getComment() {
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) return pnlOrtho.getComment();
		if(sel == TR) return pnlTrans.getComment();
		//if(sel == RH) return pnlRecip.getComment();
		return pnlCust.getComment();
	}
	
	public void setComment(String comment) {
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setComment(comment);
		else if(sel == TR) pnlTrans.setComment(comment);
		//else if(sel == RH) pnlRecip.setComment(comment);
		else pnlCust.setComment(comment);
	}

	public String getSettings() {
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) return pnlOrtho.getSettings();
		if(sel == TR) return pnlTrans.getSettings();
		//if(sel == RH) return pnlRecip.getSettings();
		return pnlCust.getSettings();
	}
	
	public void setSettings(String settings) {
		int sel = cmbMode.getSelectedIndex();
		
		if(sel == OM) pnlOrtho.setSettings(settings);
		else if(sel == TR) pnlTrans.setSettings(settings);
		//else if(sel == RH) pnlRecip.setSettings(settings);
		else pnlCust.setSettings(settings);
	}
	
	public void resetSettings() {
		pnlOrtho.resetSettings();
		pnlTrans.resetSettings();
		//pnlRecip.resetSettings();
		pnlCust.resetSettings();
	}
	
	private CompilePanel theParentPanel = null;
	private JComboBox cmbMode = null;
	private JLabel lblMode = null;
	private MethodBestRecipPanel pnlRecip = null;
	private MethodOrthoMCLPanel pnlOrtho = null;
	private MethodTransitivePanel pnlTrans = null;
	private MethodUserDefPanel pnlCust = null;
	private JButton btnKeep = null;
	private JButton btnDiscard = null;
	private JButton btnHelp = null;
	private boolean bEditMode = false;
	private boolean bLoaded = false;
}
